package fr.umlv.m2.jee.pmlv.service.note.impl;

import fr.umlv.m2.jee.pmlv.persistence.note.UserNote;
import fr.umlv.m2.jee.pmlv.persistence.note.UserThemeNote;
import fr.umlv.m2.jee.pmlv.persistence.note.dao.HibernateUserNoteDAO;
import fr.umlv.m2.jee.pmlv.persistence.note.dao.HibernateUserThemeNoteDAO;
import fr.umlv.m2.jee.pmlv.persistence.subject.Project;
import fr.umlv.m2.jee.pmlv.persistence.subject.TD;
import fr.umlv.m2.jee.pmlv.persistence.subject.TP;
import fr.umlv.m2.jee.pmlv.persistence.subject.dao.HibernateSubjectDAO;
import fr.umlv.m2.jee.pmlv.service.note.DisplayUserNote;
import fr.umlv.m2.jee.pmlv.service.note.IDisplayUserNoteService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("defautDisplayUserNoteService")
public class DefautDisplayUserNoteService implements IDisplayUserNoteService {

    @Autowired
    @Qualifier("hibernateUserNoteDAO")
    private HibernateUserNoteDAO dao;
    @Autowired
    @Qualifier("hibernateUserThemeNoteDAO")
    private HibernateUserThemeNoteDAO utndao;
    @Autowired
    @Qualifier("hibernateSubjectDAO")
    private HibernateSubjectDAO sdao;

    @Override
    @Transactional(readOnly=true)
    public List<DisplayUserNote> getNoteByUserAndByYear(String uid, int year) {
        ArrayList<DisplayUserNote> result = new ArrayList<DisplayUserNote>(16);
        for(UserNote note : dao.findNoteByUserAndByYear(uid,year)) {
                result.add(new DisplayUserNote(note));
        }
        return result;
    }

    @Override
    @Transactional(readOnly=true)
    public List<DisplayUserNote> getNoteBySubjectAndByYear(Long subjectId, int year) {
        ArrayList<DisplayUserNote> result = new ArrayList<DisplayUserNote>(16);
        for(UserNote note : dao.findNoteBySubjectAndByYear(subjectId,year)) {
                result.add(new DisplayUserNote(note));
        }
        return result;
    }

    @Override
    @Transactional(readOnly=true)
    public DisplayUserNote getNoteByUserAndSubjectAndByYear(String uid, Long subjectId, int year) {
        DisplayUserNote note = new DisplayUserNote(dao.findNoteByUserAndSubjectAndByYear(uid, subjectId, year));
        return note;
    }

    @Override
    @Transactional(readOnly=true)
    public void markExamBySubjectAndByYear(long idSubject, HashMap<String, Float> notes, int year) {
        for(String s:notes.keySet())
        {
            UserNote unote = dao.findNoteByUserAndSubjectAndByYear(s, idSubject, year);
            if(unote!=null)
            {
                if(notes.get(s)==null) unote.setNoteExam(null);
                else unote.setNoteExam(notes.get(s));
                dao.merge(unote);
            }
            else if(unote==null && notes.get(s)!=null)
            {
                unote = new UserNote();
                unote.setNote(null); unote.setNoteProject(null); unote.setNoteTD(null); unote.setNoteTP(null);
                unote.setNoteExam(notes.get(s));
                unote.setUid(s);
                unote.setYear(year);
                unote.setSubject( sdao.findById(idSubject) );
                dao.persist(unote);
            }
        }
    }

    @Override
    @Transactional(readOnly=true)
    public void markBySubjectAndByYear(long idSubject, HashMap<String, Float> notes, int year) {
        for(String s:notes.keySet())
        {
            UserNote unote = dao.findNoteByUserAndSubjectAndByYear(s, idSubject, year);
            if(unote!=null)
            {
                if(notes.get(s)==null) unote.setNote(null);
                else unote.setNote(notes.get(s));
                dao.merge(unote);
            }
            else if(unote==null && notes.get(s)!=null)
            {
                unote = new UserNote();
                unote.setNoteExam(null); unote.setNoteProject(null); unote.setNoteTD(null); unote.setNoteTP(null);
                unote.setNote(notes.get(s));
                unote.setUid(s);
                unote.setYear(year);
                unote.setSubject( sdao.findById(idSubject) );
                dao.persist(unote);
            }
        }
    }

    @Override
    @Transactional(readOnly=true)
    public void recalculMarkBySubjectAndByYear(long idSubject, String uid, int year) {
        List<UserThemeNote> themesnotes = utndao.findByUserAndSubjectAndByYear(uid, idSubject, year);
        int nbProject = 0, nbTd = 0, nbTp = 0;
        float markProject = 0.0f, markTd = 0.0f, markTp = 0.0f;
        for(UserThemeNote utn:themesnotes)
        {
            if(utn.getTheme() instanceof Project)
            {
                nbProject++; markProject = markProject + utn.getNote();
            }
            else if(utn.getTheme() instanceof TD)
            {
                nbTd++; markTd = markTd + utn.getNote();
            }
            else if(utn.getTheme() instanceof TP)
            {
                nbTp++; markTp = markTp + utn.getNote();
            }
        }

        UserNote unote = dao.findNoteByUserAndSubjectAndByYear(uid, idSubject, year);
        if(unote!=null)
        {
            if(nbProject>0) unote.setNoteProject(markProject/nbProject);
            else unote.setNoteProject(null);
            if(nbTd>0) unote.setNoteTD(markTd/nbTd);
            else unote.setNoteTD(null);
            if(nbTp>0) unote.setNoteTP(markTp/nbTp);
            else unote.setNoteTP(null);
            dao.merge(unote);
        }
        else
        {
            unote = new UserNote();
            unote.setNoteExam(null); unote.setNote(null);
            if(nbProject>0) unote.setNoteProject(markProject/nbProject);
            else unote.setNoteProject(null);
            if(nbTd>0) unote.setNoteTD(markTd/nbTd);
            else unote.setNoteTD(null);
            if(nbTp>0) unote.setNoteTP(markTp/nbTp);
            else unote.setNoteTP(null);
            unote.setUid(uid);
            unote.setYear(year);
            unote.setSubject( sdao.findById(idSubject) );
            dao.persist(unote);
        }

        System.out.println("name = "+uid+" notes="+themesnotes.size()+" td="+nbTd+" tp="+nbTp+" project="+nbProject);
    }
}
